<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body>
    <!-- 写模板 -->
    <div id="root">
      <p>{{ name }}</p>
      <p>{{ message }}</p>
    </div>

    <script>

      let reg = /\{\{(.+?)\}\}/g // ()->分组，.+->任意值，？->取消贪婪

      function compiler(template, data) {
        /* 
          1、判断template是什么数据类型（本案例是DOM元素；vue中是DOM-》字符串模板-》VNOde-》真正的DOM）
          2、判断子元素是否是文本节点
        */
      let childNodes = template.childNodes // 取出子元素
      for(let i = 0; i < childNodes.length; i++) {
        let type = childNodes[i].nodeType // 1 元素， 3 文本节点
        if(type === 3) {
          // 文本节点，可以判断里面是否有 {{}}插值
          let txt = childNodes[i].nodeValue // 该属性只有文本节点才有意义

          // 判断有没有双括号
          txt = txt.replace(reg, function(_, g) {
            let key = g.trim()
            let value = data[key]
            return value
          })

          // txt现在跟DOM元素是没有关系的
          childNodes[i].nodeValue = txt

        }
        else if(type === 1) {
          // 元素，考虑它有没有子元素，是否需要 将其子元素进行判断是否要插值
          compiler(childNodes[i], data)
        }
      } 

      }


      function JGVue(options) {
        // 习惯：内部的数据使用下划线_开头，只读数据使用$开头
        this._data = options.data
        this._el = options.el

        // 准备工作（准备模板）
        this.$el = this._templateDom = document.querySelector(this._el)
        this._parent = this._templateDom.parentNode
        
        // 渲染工作
        this.render()
      }

      // 将模板和数据结合得到 HTML加载到页面中
      JGVue.prototype.render =  function() {
        this.compiler()
      }

      // 编译 将模板与数据结合，得到真正的DOM元素
      JGVue.prototype.compiler = function() {
        // 使用模板拷贝得到一个准DOM
        let realHTMLDOM = this._templateDom.cloneNode(true)
        compiler(realHTMLDOM, this._data)
        this.update(realHTMLDOM)
      }

      // 将DOM的元素 放到页面中
      JGVue.prototype.update = function(real) {
        this._parent.replaceChild(real, document.querySelector('#root'))
      }

      let app = new JGVue({
        el: '#root',
        data: {
          name: 'rose',
          message: 'info'
        }
      })
    </script>
</body>
</html>